<?php
namespace app\controller;

use app\BaseController;
use app\model\DeviceData;
use app\model\Device as DeviceModel;
use app\model\DeviceGroup;
use think\facade\Validate;
use think\facade\Db;

class Alarm extends BaseController
{
    /**
     * 获取告警列表
     */
    public function index()
    {
        // 获取请求参数
        $params = $this->request->get();
        
        // 构建查询
        $query = DeviceData::where('is_alarm', 1);
        
        // 按设备ID筛选
        if (!empty($params['device_id'])) {
            $query = $query->where('device_id', $params['device_id']);
        }
        
        // 按设备组ID筛选
        if (!empty($params['group_id'])) {
            // 获取设备组下的所有设备ID
            $deviceIds = DeviceModel::where('group_id', $params['group_id'])->column('id');
            if (!empty($deviceIds)) {
                $query = $query->whereIn('device_id', $deviceIds);
            }
        }
        
        // 按告警类型筛选
        if (isset($params['alarm_type']) && $params['alarm_type'] !== '') {
            $query = $query->where('alarm_type', $params['alarm_type']);
        }
        
        // 按数据类型筛选
        if (!empty($params['data_type'])) {
            $query = $query->where('data_type', $params['data_type']);
        }
        
        // 按时间范围筛选
        if (!empty($params['start_time']) && !empty($params['end_time'])) {
            $query = $query->whereBetweenTime('data_time', $params['start_time'], $params['end_time']);
        }
        
        // 关联设备信息
        $query = $query->with(['device']);
        
        // 按时间倒序
        $query = $query->order('data_time', 'desc');
        
        // 分页
        $list = $query->paginate([
            'list_rows' => $params['pageSize'] ?? 10,
            'page' => $params['page'] ?? 1,
        ]);
        
        return $this->success('获取成功', $list);
    }
    
    /**
     * 获取告警统计
     */
    public function statistics()
    {
        // 获取今日告警数
        $todayCount = DeviceData::where('is_alarm', 1)
            ->whereDay('data_time')
            ->count();
        
        // 获取昨日告警数
        $yesterdayCount = DeviceData::where('is_alarm', 1)
            ->whereDay('data_time', 'yesterday')
            ->count();
        
        // 计算同比增长率
        $growthRate = $yesterdayCount > 0 ? round((($todayCount - $yesterdayCount) / $yesterdayCount) * 100, 2) : 0;
        
        // 获取各告警类型统计
        $typeStats = DeviceData::where('is_alarm', 1)
            ->field('alarm_type, COUNT(*) as count')
            ->group('alarm_type')
            ->select();
        
        // 获取告警设备TOP5
        $deviceTop = Db::name('device_data')
            ->alias('d')
            ->join('device dev', 'd.device_id = dev.id')
            ->where('d.is_alarm', 1)
            ->field([
                'dev.id',
                'dev.name',
                'COUNT(*) as count'
            ])
            ->group('d.device_id')
            ->order('count', 'desc')
            ->limit(5)
            ->select();
        
        // 获取告警数据类型TOP5
        $dataTypeTop = DeviceData::where('is_alarm', 1)
            ->field('data_type, COUNT(*) as count')
            ->group('data_type')
            ->order('count', 'desc')
            ->limit(5)
            ->select();
        
        // 获取最近7天告警趋势
        $trendData = [];
        for ($i = 6; $i >= 0; $i--) {
            $date = date('Y-m-d', strtotime("-{$i} days"));
            $count = DeviceData::where('is_alarm', 1)
                ->whereDay('data_time', $date)
                ->count();
            $trendData[] = [
                'date' => $date,
                'count' => $count
            ];
        }
        
        return $this->success('获取成功', [
            'today_count' => $todayCount,
            'yesterday_count' => $yesterdayCount,
            'growth_rate' => $growthRate,
            'type_stats' => $typeStats,
            'device_top' => $deviceTop,
            'data_type_top' => $dataTypeTop,
            'trend' => $trendData
        ]);
    }
    
    /**
     * 获取告警详情
     * @param int $id 告警数据ID
     */
    public function detail($id)
    {
        // 查询告警数据
        $alarm = DeviceData::with(['device'])->find($id);
        if (!$alarm) {
            return $this->error('告警数据不存在');
        }
        
        // 查询相同设备、相同数据类型的历史告警数据
        $history = DeviceData::where('device_id', $alarm->device_id)
            ->where('data_type', $alarm->data_type)
            ->where('is_alarm', 1)
            ->where('id', '<>', $id)
            ->order('data_time', 'desc')
            ->limit(5)
            ->select();
        
        // 查询相同设备、相同数据类型的前后数据值
        $context = DeviceData::where('device_id', $alarm->device_id)
            ->where('data_type', $alarm->data_type)
            ->whereBetweenTime('data_time', date('Y-m-d H:i:s', strtotime($alarm->data_time) - 3600), date('Y-m-d H:i:s', strtotime($alarm->data_time) + 3600))
            ->where('id', '<>', $id)
            ->order('data_time', 'asc')
            ->select();
        
        $alarm->history = $history;
        $alarm->context = $context;
        
        return $this->success('获取成功', $alarm);
    }
    
    /**
     * 处理告警
     */
    public function process()
    {
        // 获取请求数据
        $data = $this->request->post();
        
        // 验证数据
        $validate = Validate::rule([
            'id' => 'require|number',
            'status' => 'require|in:1,2,3',   // 1:已确认, 2:已处理, 3:已忽略
            'remark' => 'string',
        ]);
        
        if (!$validate->check($data)) {
            return $this->error('参数错误：' . $validate->getError());
        }
        
        // 查询告警数据
        $alarm = DeviceData::find($data['id']);
        if (!$alarm) {
            return $this->error('告警数据不存在');
        }
        
        // 更新告警处理状态
        try {
            $alarm->save([
                'process_status' => $data['status'],
                'process_time' => date('Y-m-d H:i:s'),
                'process_remark' => $data['remark'] ?? '',
                'process_user_id' => $this->request->userId ?? 0
            ]);
            
            return $this->success('处理成功');
        } catch (\Exception $e) {
            return $this->error('处理失败：' . $e->getMessage());
        }
    }
} 